package com.lenovo.nova.widget.dialog;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.*;

import com.lenovo.nova.util.Applications;
import com.lenovo.nova.util.BaseActivity;
import com.lenovo.nova.util.Constant;
import com.lenovo.nova.util.DebugUtil;
import com.lenovo.nova.util.debug.mylog;
import com.lenovo.nova.util.view.KeyUtil;
import com.lenovo.nova.utils.R;
import com.lenovo.nova.widget.dialog.buildview.DialogFragmentBuilder;
import com.lenovo.nova.widget.dialog.buildview.DefaultViewBuild;

import java.util.ArrayList;
import java.util.List;

@SuppressLint("NewApi")
public class BaseDialogFragment extends DialogFragment implements DialogInterface {
	private static final int MESSAGE_DELAY_SHOW = 0;
	private static final int MESSAGE_DELAY_HIDE = 1;
	private static final String TAG = "BaseDialogFragment";
	private Context mContext;
	private DialogFragmentBuilder builder ;
	private boolean isReadyShow;
	private OnDismissListener mOnDismissListener;
	private OnKeyListener onKeyListener;
	private boolean isDismiss;
    private boolean isDisableDarkScreen;
    private String tag;
    private long mOnCreateViewTime;

    public BaseDialogFragment() {
        mAllInstance.add(this);
		mylog.i(TAG, "BaseDialogFragment() context is  " + getActivity());
	}

    private final static List<BaseDialogFragment> mAllInstance = new ArrayList<BaseDialogFragment>();

    public static List<BaseDialogFragment> getAllInstance(){
        return mAllInstance;
    }

    public static void dismissByTag(String tag){
        BaseDialogFragment oneInstance = findInstanceByTag(tag);
        if(oneInstance != null){
            oneInstance.dismiss();
        }
    }

    public static BaseDialogFragment findInstanceByTag(String tag){
        BaseDialogFragment instance = null;
        for(int i = 0;i < mAllInstance.size(); i++){
            BaseDialogFragment tmp = mAllInstance.get(i);

            if(tmp.tag != null && tmp.tag.equals(tag)){
                instance = tmp;
                break;
            }
        }
        mylog.i(TAG,"dialog tag is " + tag + " instance  " + instance);
        return instance;
    }

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mylog.i(Constant.Debug.METHOD_TAG, getName() + "onCreate");
		if(builder == null){
			builder = new DefaultViewBuild(this);
		}
		isDismiss = false;
		onSetDefaultStyle();
		builder.onCreate(savedInstanceState);
	}


    public void debugFocus(View view){
        if(view instanceof ViewGroup){
            mylog.i(TAG,"focus " + view.isFocused() + " " + view);

            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                View child = ((ViewGroup) view).getChildAt(i);
                debugFocus(child);
            }
        }else{
            mylog.i(TAG,"focus " + view.isFocused() + " " + view);
        }


    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mylog.i(Constant.Debug.METHOD_TAG,getName() + "onDestroy");
    }

    @Override
    public void onStart() {
        super.onStart();
        mylog.i(Constant.Debug.METHOD_TAG,getName() + "onStart");
    }

    @Override
    public void onStop() {
        super.onStop();
        mylog.i(Constant.Debug.METHOD_TAG,getName() + "onStop");
    }

    @Override
    public void onResume() {
        super.onResume();
        mylog.i(Constant.Debug.METHOD_TAG,getName() + "onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        mylog.i(Constant.Debug.METHOD_TAG,getName() + "onPause");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mylog.i(Constant.Debug.METHOD_TAG, getName() + "onCreateView");
        return builder.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mylog.i(Constant.Debug.METHOD_TAG,getName() + "onDestroyView");
        mOnCreateViewTime = Long.MAX_VALUE;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        builder.onActivityCreated(savedInstanceState);
        mOnCreateViewTime = SystemClock.elapsedRealtime();
//		setCancelable(false);
        mylog.i(Constant.Debug.METHOD_TAG, getName() + "onActivityCreated");
    }

    @Override
	public Dialog onCreateDialog(Bundle savedInstanceState) {
        mylog.i(Constant.Debug.METHOD_TAG,getName()  + "onCreateDialog");
		Dialog dialog = builder.onCreateDialog(savedInstanceState);
		if(dialog == null){
			dialog = new Dialog(getActivity(), getTheme()){
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    onDialogPreCreate(this);
                    super.onCreate(savedInstanceState);
                }

                @Override
                public boolean dispatchTouchEvent(MotionEvent ev) {
                    if(Applications.isInDebugMode){
                        mylog.d(Constant.Debug.METHOD_TAG,getName() + "dispatchTouchEvent " + ev);
                    }
                    BaseActivity.inputModeChangeTouchMode(getContext());

                    if(onDispatchTouchEvent(ev)){
                        return true;
                    }

                    return super.dispatchTouchEvent(ev);
                }

                @Override
                public boolean dispatchGenericMotionEvent(MotionEvent ev) {
                    if(Applications.isInDebugMode){
                        mylog.d(Constant.Debug.METHOD_TAG,getName() + "dispatchGenericMotionEvent " + ev);
                    }

                    if (ev.getAction() == MotionEvent.ACTION_HOVER_MOVE || ev.getAction() == MotionEvent.ACTION_HOVER_ENTER || ev.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
                        BaseActivity.inputModeChangeTouchMode(getContext());
                    }

                    Applications.get(getContext()).notifyMotionEventChangeListener(ev);
                    return super.dispatchGenericMotionEvent(ev);
                }

                @Override
                public boolean dispatchKeyEvent(KeyEvent event) {
                    mylog.d(Constant.Debug.METHOD_TAG,getName() + "dispatchKeyEvent " + event);
                    BaseActivity.inputModeChangeToKeyBoard(getContext(), event.getKeyCode());

                    if(KeyUtil.isTouchBoardKey(event.getKeyCode())){
                        Applications.get().notifyTouchBoardTouched(event);
                    }

                    if(onDispatchKeyEvent(event)){
                        return true;
                    }

                    return super.dispatchKeyEvent(event);
                }
            };
		}

//        Window window = dialog.getWindow();
//        WindowManager.LayoutParams params = window.getAttributes();
//        params.dimAmount = 0.0f;
//        window.setAttributes(params);

        if(onKeyListener != null){
            dialog.setOnKeyListener(onKeyListener);
        }
        onDialogPreCreate(dialog);


		return dialog;
	}

    protected boolean onDispatchKeyEvent(KeyEvent event) {
        return false;
    }

    protected boolean onDispatchTouchEvent(MotionEvent ev) {
        return false;
    }

    protected void onDialogPreCreate(Dialog dialog){

    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mylog.i(Constant.Debug.METHOD_TAG, getName() + "onAttach " + activity);
        if(builder != null){
            builder.onAttach(activity);
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mylog.i(Constant.Debug.METHOD_TAG, getName() + "onDetach");
        builder.onDetach();
    }

    @Override
    public void dismiss() {
        if(mContext instanceof Activity){
            if(((Activity) mContext).isDestroyed() || ((Activity) mContext).isFinishing()){
                return;
            }
        }
        mylog.i(TAG, "dismiss");
        isReadyShow = false;
        isDismiss = true;

        try {
            if(getFragmentManager() != null){
                super.dismiss();
            }
        } catch (Exception e) {
            mylog.i(TAG, "dismiss", 2);
            e.printStackTrace();
        }

    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        mylog.i(TAG, "onDismiss");
        if(mOnDismissListener != null){
            mOnDismissListener.onDismiss(dialog);
        }
        isReadyShow = false;
        isDismiss = true;
        mAllInstance.remove(this);
    }

    @Override
    public void cancel() {
        getDialog().cancel();
    }

    public long getDialogShowTimeMillie(){
        return SystemClock.elapsedRealtime() - mOnCreateViewTime;
    }

    public void disableDarkScreen(){
        isDisableDarkScreen = true;
    }

	public boolean isReadyShow(){
		return isReadyShow;
	}

	public boolean isDismiss(){
		return isDismiss;
	}

	public void setOnDismissListener(OnDismissListener l){
		mOnDismissListener = l;
	}
	
	public void setOnKeyListener(OnKeyListener l){
		this.onKeyListener = l;
	}

	public void setViewBuilder(DialogFragmentBuilder builder){
		this.builder = builder;
	}
	
    public void setTitle(CharSequence title) {
    	if(builder == null){
			builder = new DefaultViewBuild(this);
		}
    	
        this.builder.setTitle(title);
    }
	
    public void setMessage(CharSequence msg){
    	if(builder == null){
			builder = new DefaultViewBuild(this);
		}
    	this.builder.setMessage(msg);
    }

    public void setButton(int which,CharSequence msg,android.content.DialogInterface.OnClickListener l){
        builder.setButton(which, msg,l);
    }

    public void setView(View v){
        builder.setView(v);
    }

    protected void onSetDefaultStyle() {
//		setStyle(DialogFragment.STYLE_NORMAL, MResourceUtil.getStyleId(getActivity(), "scenic_util_dialog_theme"));
        if(isDisableDarkScreen){
            setStyle(DialogFragment.STYLE_NORMAL, R.style.scenic_util_dialog_theme_disable_dark);
        }else{
            setStyle(DialogFragment.STYLE_NORMAL, R.style.scenic_util_dialog_theme);
        }
    }

    public void onDumpExecute(DebugUtil util,String cmdValue){

    }

    public void show(Activity context,String tag){
        String name = tag;

        if(tag == null){
            name = "Null_Tag";
        }else{
            BaseDialogFragment oneInstance = findInstanceByTag(tag);
            if(oneInstance != null){
                oneInstance.dismiss();
                mAllInstance.remove(oneInstance);
            }
        }

        mContext = context;
        mylog.i(TAG,"tag is " + name,3);

        try {
            this.tag = tag;
            show(context.getFragmentManager(), name);
            isReadyShow = true;
        } catch (IllegalStateException e) {
            //Can not perform this action after onSaveInstanceState
            FragmentTransaction ft = context.getFragmentManager().beginTransaction();
            ft.add(this, name);
            ft.commitAllowingStateLoss();
            e.printStackTrace();
        }

    }

	public void show(Activity context){
        show(context,null);
    }
	
	public void show(Activity context,long duration){
		show(context);
		
		Message msg = new Message();
		msg.what = MESSAGE_DELAY_HIDE;
		msg.obj = context;
		isReadyShow = true;
		mHandler.sendMessageDelayed(msg, duration);
	}

	@SuppressLint("HandlerLeak")
	private Handler mHandler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			switch(msg.what){
			case MESSAGE_DELAY_SHOW:
				show((Activity)msg.obj);
				break;
			case MESSAGE_DELAY_HIDE:
				dismiss();
				break;
			}
		}
	};

    private String getName(){

        if(tag != null){
            return tag;
        }

        return getClass().getSimpleName()+":"+hashCode()+" ";
    }

    @Override
    public String toString() {
        if(tag == null){
            return super.toString();
        }
        return tag;
    }
}
